<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<style type="text/css">
	body {
		background: #404066;
		color: #000000;
		font: 10pt verdana, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif;
		margin: 5px 10px 10px 10px;
		padding: 0px;
		overflow: hidden;
	}
	h1 {
		color: darkblue;
		font :bold 16pt verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif;
		margin-top: 0
	}
	.title {
		text-align: center;
	}
	h2 {
		color:darkblue;
		font:bold 14pt verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif
	}
	h3 {
		color:darkblue;
		font:bold 12pt verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif
	}
	h4 {
		color:#b73235;
		font:bold 10pt verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif
	}
	pre {
		font: 10pt parallax,courier,monospaced;
		line-height: 97%;
	}	
	.source {
		margin-left: 20px;
		border: 1px solid #ccc;
		overflow: auto;
		display: none;
		background: #f8f8e8;
		margin-top: 12pt;
		width: 95%;
		padding-top: 5px;
		padding-left: 10px;
		max-height: 600px;
		letter-spacing: 0px;
	}
	var {
		color: #000080;
		font-style: normal;
		font-weight: bold;
		letter-spacing: -1px;
	}
	a {
		font-weight: bold;
		font-size: 6pt;
		text-decoration: none;
		color: #0000cc;
	}
	.toc1 {
		font-size: 12pt;
		font-weight: bold;
		vertical-align: baseline;
		text-align: center;
		color: #d7d0ff;
	}		
	.toc2 {
		font-size: 95%;
		font-weight: bold;
		vertical-align: baseline;
		color: white;
		text-decoration: none;
	}		
	.toc3 {
		font-size: 90%;
		font-weight: normal;
		vertical-align: baseline;
		margin-left: 10px;
		color: white;
		text-decoration: none;
	}		
	.toc4 {
		font-size: 85%;
		font-weight: normal;
		font-style: italic;
		vertical-align: baseline;
		margin-left: 20px;
		color: #d7d0ff;
		text-decoration: none;
	}
	.tocgrp {
		display: none
	}
  hr {
  	border: 0;
    color: #b73235;
    background-color: #b73235;
    height: 1px;
  }
	</style>
	<script language="JavaScript">
		window.onload = resize;
		window.onresize = resize;
		var show=0;
		function ShowHide(divId) {
			if (document.getElementById(divId).style.display!='block') {
				document.getElementById(divId).style.display='block';
				if (divId.substring(0, 3) == 'toc') {
					window.location = '#lbl' + divId.substring(3);
				}
			} else {
				document.getElementById(divId).style.display='none';
			}
		};
    function resize() {
      var myWidth = 0, myHeight = 0;
      if(typeof(window.innerWidth) == 'number') {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
      } else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
      } else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
      }
      document.getElementById("text").style.height = (myHeight - 10) + "px";
      document.getElementById("text").style.width = (Math.min(myWidth - 250, 800)) + "px";
      document.getElementById("toc").style.height = (myHeight - 10) + "px";
     }	
    function selectall(source) { 
	    var selection, range, doc, win; 
	    if ( (doc = source.ownerDocument)
	    	&& (win = doc.defaultView)
	    	&& typeof win.getSelection != 'undefined'
	    	&& typeof doc.createRange != 'undefined' 
	    	&& (selection = window.getSelection())
	    	&& typeof selection.removeAllRanges != 'undefined'
	    ) { 
	       range = doc.createRange(); 
	       range.selectNode(source); 
	       selection.removeAllRanges(); 
	       selection.addRange(range); 
	    } else if (document.body && typeof document.body.createTextRange != 'undefined' && (range = document.body.createTextRange())) { 
	       range.moveToElementText(source); 
	       range.select(); 
	    } 
		}
  </script>
</head>
<body style = "margin: 0 0 0 0;">
<div align=center>
<table cellpadding=0 cols=2 border=0>
	<tr><td valign="top">
	<div id="toc" style= "width: 200px; height: 600px; overflow: auto; background-color: #222255; border-left: solid #ffffe0"><br/>
		<div style="background-color:#222255; width: 100%; text-align: center">
		<img src="data:image/gif;base64,
			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
		">
		</div>
		<div style="font: bold 11pt verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif;color:white; text-align: center; margin-bottom: 10px; margin-top: 10px">HTTPHEADER</div>
		<p class = "toc1">Table of Contents</p>
		<div style = "text-align: left; margin-left: 10px;">
			<a href= "#lbl1" class = "toc2">Preface</a><br/>
<a onclick ="javascript:ShowHide('toc2')" href="javascript:;" class = "toc2">Global CONstants ... </a><br />
<div id= "toc2" class = "tocgrp">
</div>
<a href= "#lbl4" class = "toc2">Global DATa </a><br/>
<a href= "#lbl6" class = "toc2">PUBlic Spin Methods</a><br/>
<a href= "#lbl7" class = "toc4">Get</a><br/>
<a href= "#lbl9" class = "toc4">Header</a><br/>
<a href= "#lbl11" class = "toc4">Post</a><br/>
<a href= "#lbl13" class = "toc4">Request</a><br/>
<a href= "#lbl15" class = "toc4">UrlContains</a><br/>
<a href= "#lbl17" class = "toc4">GetUrlPart</a><br/>
<a href= "#lbl19" class = "toc4">GetFileName</a><br/>
<a href= "#lbl21" class = "toc4">GetFileNameExtension</a><br/>
<a href= "#lbl23" class = "toc4">_GetFileNameExtension</a><br/>
<a href= "#lbl25" class = "toc4">Decode</a><br/>
<a href= "#lbl27" class = "toc4">GetTokens</a><br/>
<a href= "#lbl29" class = "toc4">EnumerateHeader</a><br/>
<a href= "#lbl31" class = "toc4">TokenizeHeader</a><br/>
<a href= "#lbl33" class = "toc4">TokenizeFilename </a><br/>
<a onclick ="javascript:ShowHide('toc35')" href="javascript:;" class = "toc2">PRIvate Spin Methods ... </a><br />
<div id= "toc35" class = "tocgrp">
<a href= "#lbl36" class = "toc4">FindBody</a><br/>
<a href= "#lbl38" class = "toc4">IsStatusLineToken</a><br/>
<a href= "#lbl40" class = "toc4">IsHeaderToken</a><br/>
<a href= "#lbl42" class = "toc4">IsPostToken</a><br/>
<a href= "#lbl44" class = "toc4">IsEndOfLine</a><br/>
<a href= "#lbl46" class = "toc4">DecodeString</a><br/>
</div>
<a onclick ="javascript:ShowHide('toc48')" href="javascript:;" class = "toc2">PUB Debug Stuff ... </a><br />
<div id= "toc48" class = "tocgrp">
<a href= "#lbl49" class = "toc4">GetStatusLine</a><br/>
<a href= "#lbl51" class = "toc4">GetHeaderLines</a><br/>
<a href= "#lbl53" class = "toc4">GetBody</a><br/>
<a href= "#lbl55" class = "toc4">GetStatusLineTokenCount</a><br/>
<a href= "#lbl57" class = "toc4">GetHeaderLinesTokenCount</a><br/>
<a href= "#lbl59" class = "toc4">GetBodyTokenCount</a><br/>
</div>
<a href= "#lbl61" class = "toc2">Documentation </a><br/>
<a href= "#lbl62" class = "toc2">MIT License </a><br/>

		</div>
	</div>
	</td>
	<td>
		<div id="text" style= "text-align: left; padding-left: 20px; padding-right: 20px; width: 800px; height: 600px; background-color: #ffffe0; overflow: auto">
			<h1 id = "lbl1" class = "title">HttpHeader </h1>

<br /><br />
AUTHORS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mike Gebhard / Michael Sommer<br />
COPYRIGHT:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parallax Inc. - See LICENCE (MIT)<br />
LAST MODIFIED:&nbsp;&nbsp;&nbsp;&nbsp;10/04/2013<br />
VERSION:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.0<br />
LICENSE:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MIT (see end of file)<br /><br />
DESCRIPTION:&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The HttpHeader object<br />
<br />
MODIFICATIONS:<br />
 8/31/2013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this version DOES NOT tokenize the Filename inside TokenizeHeader<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;so '/' is allowed in Filename and in POST/GET parameters<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for RESTful Interfaces you can call TokenizeFilename after TokenizeHeader<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to provide url_parts as values<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;So before calling TokenizeFilename<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- GetFileName will return the path and filename<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And after calling TokenizeFilename<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- GetFileName will just return the filename without path<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- GetUrlPart(index) will work as desired and will<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enumerate each part of the path &amp; filename<br />
10/04/2013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;added minimal spindoc comments<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Michael Sommer (MSrobots)<br />

<br />
<h2 id = "lbl2">Global CONstants </h2>
<br /><a onclick ="javascript:ShowHide('lbl3')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl3>  
  CR    = $0D
  LF    = $0A
  
  TOKEN_PTR_LEN       = $FF
  HEADER_SECTIONS_LEN = 4
  FILE_EXTENSION_LEN  = 3

  #0, STATUS_LINE, HEADER_LINES, BODY, URL_PARTS

</pre>
<hr />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<h2 id = "lbl4">Global DATa </h2>
<br /><a onclick ="javascript:ShowHide('lbl5')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl5>
  ext             <var>long</var>
                  <var>byte</var>  $0[3], $0               ' needs to be long alignt

  index           <var>byte</var>  "/index.htm", $0
  sectionTokenCnt <var>byte</var>  $0[HEADER_SECTIONS_LEN]
  tokens          <var>byte</var>  $0 
  null            <var>long</var>  $0
  headerSections  <var>long</var>  $0[HEADER_SECTIONS_LEN]
  tokenPtr        <var>long</var>  $0[TOKEN_PTR_LEN]
  ptr             <var>long</var>  $0
  isToken         <var>long</var>  $0
  t1              <var>long</var>  $0

</pre>
<hr /><br />
<h2 id = "lbl6">PUBlic Spin Methods</h2>
<hr /><h4 id = "lbl7">Get(key)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl8')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl8><var>PUB</var> Get(key) | i
  <var>repeat</var> i <var>from</var> 0 <var>to</var> sectionTokenCnt[STATUS_LINE]-1
    <var>if</var>(<var>strcomp</var>(key, tokenPtr[i]))
      <var>return</var> tokenPtr[i+1]
  <var>return</var> @null

</pre>
<hr /><h4 id = "lbl9">Header(key)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl10')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl10><var>PUB</var> Header(key) | i
  <var>repeat</var> i <var>from</var> sectionTokenCnt[STATUS_LINE] <var>to</var> sectionTokenCnt[HEADER_LINES]
    <var>if</var>(<var>strcomp</var>(key, tokenPtr[i]))
        <var>return</var> tokenPtr[i+1]
  <var>return</var> @null

</pre>
<hr /><h4 id = "lbl11">Post(key)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl12')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl12><var>PUB</var> Post(key) | i
  <var>repeat</var> i <var>from</var> sectionTokenCnt[HEADER_LINES] <var>to</var> sectionTokenCnt[BODY]
    <var>if</var>(<var>strcomp</var>(key, tokenPtr[i]))
        <var>return</var> tokenPtr[i+1]
  <var>return</var> @null

</pre>
<hr /><h4 id = "lbl13">Request(key)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl14')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl14><var>PUB</var> Request(key) | i
  <var>repeat</var> i <var>from</var> 0 <var>to</var> sectionTokenCnt[BODY]-1
    <var>if</var>(<var>strcomp</var>(key, tokenPtr[i]))
      <var>return</var> tokenPtr[i+1]
  <var>return</var> @null

</pre>
<hr /><h4 id = "lbl15">UrlContains(value)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl16')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl16><var>PUB</var> UrlContains(value) | i, j, adr, size
  <var>ifnot</var> sectionTokenCnt[URL_PARTS] == sectionTokenCnt[BODY]' Filename already tokenized
    <var>repeat</var> i <var>from</var> sectionTokenCnt[BODY] <var>to</var> sectionTokenCnt[URL_PARTS]
      <var>if</var>(<var>strcomp</var>(value, tokenPtr[i]))                   ' check URL_PARTS
        <var>return</var> <var>true</var>
        
  <var>repeat</var> i <var>from</var> 1 <var>to</var> sectionTokenCnt[STATUS_LINE]-3
    adr := tokenPtr[i]                                  ' get token
    size := <var>strsize</var>(t1) - <var>strsize</var>(value)                ' compare length
    <var>if</var> size=&gt;0                                          ' if ok
      <var>repeat</var> j <var>from</var> 0 <var>to</var> size                           '   check all possible positions
        <var>if</var>(<var>strcomp</var>(value, adr + j))                     '   in token.
          <var>return</var> <var>true</var>
          
  <var>return</var> <var>false</var>

</pre>
<hr /><h4 id = "lbl17">GetUrlPart(value)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl18')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl18><var>PUB</var> GetUrlPart(value) 
  <var>if</var>(sectionTokenCnt[STATUS_LINE] == 3)                 ' why that?
    <var>return</var> string("/")                                  ' ??? MSrobots
    
  <var>ifnot</var> sectionTokenCnt[URL_PARTS] == sectionTokenCnt[BODY]' Filename already tokenized
    <var>if</var> value &gt; (sectionTokenCnt[URL_PARTS] - sectionTokenCnt[BODY])
      <var>return</var> @null
    <var>if</var> value&lt;1
      <var>return</var> tokenPtr[0] 
    <var>return</var> tokenPtr[sectionTokenCnt[BODY] + value-1]   
  <var>else</var>
    <var>if</var>((value &gt;  sectionTokenCnt[STATUS_LINE]-3) <var>OR</var> (++value &gt; sectionTokenCnt[STATUS_LINE]-3))
      <var>return</var> @null
      
    <var>return</var> EnumerateHeader(value)

</pre>
<hr /><h4 id = "lbl19">GetFileName
</h4>
<br /><a onclick ="javascript:ShowHide('lbl20')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl20><var>PUB</var> GetFileName
  <var>if</var> sectionTokenCnt[URL_PARTS] == sectionTokenCnt[BODY]' complete request Path &amp; File
    <var>if</var> <var>strsize</var>(tokenPtr[1])&gt;1
      <var>return</var> tokenPtr[1]                                ' without get-params (?&amp;...)
    <var>else</var>
      <var>return</var> @index
  <var>else</var>                                                  ' Filename already tokenized
    <var>return</var> tokenPtr[sectionTokenCnt[URL_PARTS]-1]         ' last URL token ? one less?
{  
  <var>repeat</var> i <var>from</var> 1 <var>to</var> sectionTokenCnt[STATUS_LINE]-2
    t1 := tokenPtr[i]
    <var>repeat</var> j <var>from</var> 0 <var>to</var> <var>strsize</var>(t1)-1
      <var>if</var>(<var>byte</var>[t1][j] == ".")
        <var>return</var> tokenPtr[i]
  <var>return</var> @index
}

</pre>
<hr /><h4 id = "lbl21">GetFileNameExtension
</h4>
<br /><a onclick ="javascript:ShowHide('lbl22')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl22><var>PUB</var> GetFileNameExtension
  <var>return</var> @ext

</pre>
<hr /><h4 id = "lbl23">_GetFileNameExtension
</h4>
<br /><a onclick ="javascript:ShowHide('lbl24')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl24><var>PRI</var> _GetFileNameExtension | j
  t1 := tokenPtr[1]  
  <var>repeat</var> j <var>from</var> <var>strsize</var>(t1)-6 <var>to</var> <var>strsize</var>(t1)-1
    <var>if</var>(<var>byte</var>[t1][j] == ".")
      <var>return</var> tokenPtr[1]+j+1
      
  <var>return</var> @index + <var>strsize</var>(@index)-FILE_EXTENSION_LEN 
{      
  <var>repeat</var> i <var>from</var> 1 <var>to</var> sectionTokenCnt[STATUS_LINE]-2
    t1 := tokenPtr[i]
    <var>repeat</var> j <var>from</var> 0 <var>to</var> <var>strsize</var>(t1)-1
      <var>if</var>(<var>byte</var>[t1][j] == ".")
        <var>return</var> tokenPtr[i]+j+1
  <var>return</var> @index + <var>strsize</var>(@index)-FILE_EXTENSION_LEN   
}

</pre>
<hr /><h4 id = "lbl25">Decode(value)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl26')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl26><var>PUB</var> Decode(value)
  DecodeString(value)
  <var>return</var> value

</pre>
<hr /><h4 id = "lbl27">GetTokens
</h4>
<br /><a onclick ="javascript:ShowHide('lbl28')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl28><var>PUB</var> GetTokens
  <var>return</var> tokens

</pre>
<hr /><h4 id = "lbl29">EnumerateHeader(idx)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl30')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl30><var>PUB</var> EnumerateHeader(idx)
  <var>return</var> tokenPtr[idx]

</pre>
<hr /><h4 id = "lbl31">TokenizeHeader(buff, len)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl32')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl32><var>PUB</var> TokenizeHeader(buff, len)
  ptr := buff
  tokens := 0
  isToken := <var>false</var>

  'Initialize pointer arrays
  'Mark the start of the status line
  tokenPtr[tokens++] := buff
  headerSections[STATUS_LINE] := buff
    
  'Parse the status line 
  <var>repeat</var> <var>until</var> IsEndOfLine(<var>byte</var>[ptr]) 
    <var>if</var>(IsStatusLineToken(<var>byte</var>[ptr]))
      <var>byte</var>[ptr++] := 0
      isToken := <var>true</var>
    <var>else</var>
      <var>if</var>(isToken)
        tokenPtr[tokens++] := ptr++
        isToken := <var>false</var>
      <var>else</var>        
        ptr++

  'Terminate the status line CR LF
  isToken := <var>false</var> 
  <var>repeat</var> <var>until</var> <var>NOT</var> IsEndOfLine(<var>byte</var>[ptr])
    <var>byte</var>[ptr++] := 0

  'Save the file type
  <var>bytemove</var>(@ext, _GetFileNameExtension, 3)

  'Mark the start of the header lines
  sectionTokenCnt[STATUS_LINE] := tokens 
  headerSections[HEADER_LINES] := ptr
  tokenPtr[tokens++] := ptr

  t1 := FindBody(ptr, <var>strsize</var>(tokenPtr[tokens-1]) )
  
  'Tokenize the the header lines
  <var>repeat</var> <var>until</var> ptr &gt; t1-1
    <var>if</var>(IsHeaderToken(<var>byte</var>[ptr], <var>byte</var>[ptr+1]))   
      <var>byte</var>[ptr++] := 0
      isToken := <var>true</var>
    <var>else</var>
      <var>if</var>(isToken)
        <var>if</var>(<var>byte</var>[ptr] == $20)
          ptr++
        tokenPtr[tokens++] := ptr++
        isToken := <var>false</var>
      <var>else</var>        
        ptr++

  sectionTokenCnt[HEADER_LINES] := tokens
  
  'Skip the two end of line chars
  <var>repeat</var> <var>until</var> <var>NOT</var> IsEndOfLine(<var>byte</var>[ptr])
    <var>byte</var>[ptr++] := 0

  'Mark the start of the body
  headerSections[BODY] := ptr

  'Decode the url
  <var>repeat</var> t1 <var>from</var> 1 <var>to</var> sectionTokenCnt[STATUS_LINE]-3
    DecodeString(tokenPtr[t1])

  'Return if body does not contain data                 
  <var>if</var>(ptr == (buff + len))                              
    sectionTokenCnt[URL_PARTS] := sectionTokenCnt[BODY] := sectionTokenCnt[HEADER_LINES] 
    <var>return</var> 0

  'Decode POST data
  <var>if</var>(<var>strcomp</var>(tokenPtr[0], string("POST")))
    <var>result</var> := ptr
    DecodeString(ptr)
                                                        ' just tokenize Body on POST
    'Tokenize the body
    tokenPtr[tokens++] := ptr++
    <var>repeat</var> <var>until</var> ptr &gt; (buff + len)-1
      <var>if</var>(IsPostToken(<var>byte</var>[ptr]))    
        <var>byte</var>[ptr++] := 0
        <var>if</var>(IsPostToken(<var>byte</var>[ptr]))
          tokenPtr[tokens++] := ptr -1
        <var>else</var>
          isToken := <var>true</var>
      <var>else</var>
        <var>if</var>(isToken)
'          if(byte[ptr] == $20)
'            ptr++
          tokenPtr[tokens++] := ptr++
          isToken := <var>false</var>
        <var>else</var>        
          ptr++
          
    sectionTokenCnt[URL_PARTS] := sectionTokenCnt[BODY] := tokens
    'return 1

</pre>
<hr /><h4 id = "lbl33">TokenizeFilename 
</h4>
<br /><a onclick ="javascript:ShowHide('lbl34')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl34><var>PUB</var> TokenizeFilename 
  <var>ifnot</var> sectionTokenCnt[URL_PARTS] == sectionTokenCnt[BODY]' Filename already tokenized
    ptr := tokenPtr[1]
    
    <var>if</var> <var>byte</var>[ptr] == "/"                                 ' if /                          '
      <var>ifnot</var> <var>byte</var>[ptr+1] == 0                            ' but not just /
        ptr++                                           ' ignore /
    headerSections[URL_PARTS] := ptr
    tokenPtr[tokens++] := ptr
    <var>ifnot</var> <var>byte</var>[ptr]==0                                  ' if not done already
      <var>repeat</var> <var>until</var> <var>byte</var>[ptr]==0
        <var>if</var> <var>byte</var>[ptr] == "/"                             ' if / found next token
          <var>byte</var>[ptr] := 0
          tokenPtr[tokens++] := ptr+1 
        ptr++        
    
    sectionTokenCnt[URL_PARTS] := tokens

</pre>
<hr /><br />
<h2 id = "lbl35">PRIvate Spin Methods </h2>
<hr /><h4 id = "lbl36">FindBody(value, len)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl37')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl37><var>PRI</var> FindBody(value, len)
  <var>repeat</var> len
    <var>if</var>(<var>byte</var>[value] == CR <var>AND</var> <var>byte</var>[value+1] == LF <var>AND</var> <var>byte</var>[value+2] == CR <var>AND</var> <var>byte</var>[value+3] == LF)
      <var>return</var> value
    <var>if</var>(<var>byte</var>[value] == LF  <var>AND</var> <var>byte</var>[value+1] == LF)
      <var>return</var> value
    value++ 
  <var>return</var> null

</pre>
<hr /><h4 id = "lbl38">IsStatusLineToken(value)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl39')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl39><var>PRI</var> IsStatusLineToken(value)
  'return lookdown(value &amp; $FF: "/", "?", "=", "+", " ", "&amp;")
  <var>return</var> <var>lookdown</var>(value &amp; $FF:  "?", "=", "+", " ", "&amp;")

</pre>
<hr /><h4 id = "lbl40">IsHeaderToken(value1, value2)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl41')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl41><var>PRI</var> IsHeaderToken(value1, value2)
  <var>if</var>(value1 == ":" <var>AND</var> <var>NOT</var> value2 == " ")
    <var>return</var> <var>false</var>
  <var>return</var> <var>lookdown</var>(value1: ":", CR, LF)

</pre>
<hr /><h4 id = "lbl42">IsPostToken(value)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl43')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl43><var>PRI</var> IsPostToken(value)
  <var>return</var> <var>lookdown</var>(value &amp; $FF: "=", "+", "&amp;")    

</pre>
<hr /><h4 id = "lbl44">IsEndOfLine(value)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl45')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl45><var>PRI</var> IsEndOfLine(value)
  <var>return</var> <var>lookdown</var>(value: CR, LF)

</pre>
<hr /><h4 id = "lbl46">DecodeString(source)
</h4>
<br /><a onclick ="javascript:ShowHide('lbl47')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl47><var>PRI</var> DecodeString(source) | char, inPlace, outPlace
  inPlace := outPlace := 0
  <var>repeat</var>
    'TODO: Handle HTML encoing ie &amp;alt;  
    char := <var>byte</var>[source][inPlace++]
    <var>if</var> (char == "%") ' convert %## back into a character
      ' first nibble
      char := <var>byte</var>[source][inPlace++] - 48
      <var>if</var> (char &gt; 9)
        char -= 7
      char := char &lt;&lt; 4
      <var>byte</var>[source][outPlace] := char
      ' second nibble
      char := <var>byte</var>[source][inPlace++] - 48
      <var>if</var> (char &gt; 9)
        char -= 7
      <var>byte</var>[source][outPlace++] += char
      ' since we trashed char doing the decode, we need this to keep the loop going
      char := "x"
    <var>elseif</var> (char == "+") ' convert + back to a space
      <var>byte</var>[source][outPlace++] := " "
    <var>else</var> ' no conversion needed, just set the character
      <var>byte</var>[source][outPlace++] := char
  <var>until</var> (char == 0)
    
  <var>byte</var>[source][outPlace-1] := 0 ' terminate the string at it's new shorter size

</pre>
<hr /><br />
<h2 id = "lbl48">PUB Debug Stuff </h2>
<hr /><h4 id = "lbl49">GetStatusLine
</h4>
<br /><a onclick ="javascript:ShowHide('lbl50')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl50><var>PUB</var> GetStatusLine
  <var>return</var> headerSections[STATUS_LINE]

</pre>
<hr /><h4 id = "lbl51">GetHeaderLines
</h4>
<br /><a onclick ="javascript:ShowHide('lbl52')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl52><var>PUB</var> GetHeaderLines
  <var>return</var> headerSections[HEADER_LINES]

</pre>
<hr /><h4 id = "lbl53">GetBody
</h4>
<br /><a onclick ="javascript:ShowHide('lbl54')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl54><var>PUB</var> GetBody
  <var>return</var> headerSections[BODY]

</pre>
<hr /><h4 id = "lbl55">GetStatusLineTokenCount
</h4>
<br /><a onclick ="javascript:ShowHide('lbl56')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl56><var>PUB</var> GetStatusLineTokenCount
  <var>return</var> sectionTokenCnt[STATUS_LINE]

</pre>
<hr /><h4 id = "lbl57">GetHeaderLinesTokenCount
</h4>
<br /><a onclick ="javascript:ShowHide('lbl58')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl58><var>PUB</var> GetHeaderLinesTokenCount
  <var>return</var> sectionTokenCnt[HEADER_LINES]  - sectionTokenCnt[STATUS_LINE]

</pre>
<hr /><h4 id = "lbl59">GetBodyTokenCount
</h4>
<br /><a onclick ="javascript:ShowHide('lbl60')" href="javascript:;">SOURCE CODE...</a>
<pre class=source id=lbl60><var>PUB</var> GetBodyTokenCount
  <var>return</var>  sectionTokenCnt[BODY] - sectionTokenCnt[HEADER_LINES]

</pre>
<hr /><br />
<h2 id = "lbl61">Documentation </h2>
<pre>
This .spin file supports PhiPi's great Spin Code Documenter found at
http://www.phipi.com/spin2html/

You can at any time create a .htm Documentation out of the .spin source.

If you change the .spin file you can (re)create the .htm file by uploading your .spin file
to http://www.phipi.com/spin2html/ and then saving the the created .htm page. 
</pre>
<br />
<h2 id = "lbl62">MIT License </h2>
<pre>
 ______________________________________________________________________________________
|                            TERMS OF USE: MIT License                                 |                                                            
|______________________________________________________________________________________|
|Permission is hereby granted, free of charge, to any person obtaining a copy of this  |
|software and associated documentation files (the "Software"), to deal in the Software |
|without restriction, including without limitation the rights to use, copy, modify,    |
|merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    |
|permit persons to whom the Software is furnished to do so, subject to the following   |
|conditions:                                                                           |
|                                                                                      |
|The above copyright notice and this permission notice shall be included in all copies |
|or substantial portions of the Software.                                              |
|                                                                                      |
|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   |
|INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         |
|PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    |
|HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  |
|CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  |
|OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         |
|______________________________________________________________________________________|
</pre>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
		</div>
	</td></tr>
</table>
</div>
</body>
</html>	
